/*
 * Copyright [2022] [https://www.xiaonuo.vip]
 *
 * Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *
 * 1.请不要删除和修改根目录下的LICENSE文件。
 * 2.请不要删除和修改Snowy源码头部的版权声明。
 * 3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 * 4.分发源码时候，请注明软件出处 https://www.xiaonuo.vip
 * 5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 * 6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package vip.xiaonuo.biz.modular.watchtask.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.auth.core.pojo.SaBaseLoginUser;
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
import vip.xiaonuo.biz.modular.appletuser.entity.AppletUser;
import vip.xiaonuo.biz.modular.appletuser.mapper.AppletUserMapper;
import vip.xiaonuo.biz.modular.hiddenreport.entity.HiddenReport;
import vip.xiaonuo.biz.modular.hiddenreport.enums.AuditResultEnum;
import vip.xiaonuo.biz.modular.hiddenreport.mapper.HiddenReportMapper;
import vip.xiaonuo.biz.modular.rewardslog.service.RewardsLogService;
import vip.xiaonuo.biz.modular.user.entity.BizUser;
import vip.xiaonuo.biz.modular.user.mapper.BizUserMapper;
import vip.xiaonuo.biz.modular.watchtask.entity.Task;
import vip.xiaonuo.biz.modular.watchtask.entity.TaskAssignment;
import vip.xiaonuo.biz.modular.watchtask.entity.TaskAuditRecord;
import vip.xiaonuo.biz.modular.watchtask.enums.AssignmentStatusEnum;
import vip.xiaonuo.biz.modular.watchtask.enums.TaskApprovalEnum;
import vip.xiaonuo.biz.modular.watchtask.enums.TaskCurrentStatusEnum;
import vip.xiaonuo.biz.modular.watchtask.mapper.TaskAssignmentMapper;
import vip.xiaonuo.biz.modular.watchtask.mapper.TaskMapper;
import vip.xiaonuo.biz.modular.watchtask.param.*;
import vip.xiaonuo.biz.modular.watchtask.service.TaskAuditRecordService;
import vip.xiaonuo.biz.modular.watchtask.service.TaskService;
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.page.CommonPageRequest;

import javax.annotation.Resource;
import java.util.List;

/**
 * 任务表Service接口实现类
 *
 * @author H
 * @date  2025/11/19 14:24
 **/
@Service
public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements TaskService {
    @Resource
    private BizUserMapper bizUserMapper;
    @Resource
    private HiddenReportMapper hiddenReportMapper;
    @Resource
    private TaskAuditRecordService taskAuditRecordService;
    @Resource
    private AppletUserMapper appletUserMapper;
    @Resource
    private TaskAssignmentMapper taskAssignmentMapper;
    @Resource
    private RewardsLogService rewardsLogService;

    @Override
    public Page<Task> page(TaskPageParam taskPageParam) {
        QueryWrapper<Task> queryWrapper = new QueryWrapper<>();
        if(ObjectUtil.isNotEmpty(taskPageParam.getApproval())) {
            queryWrapper.lambda().eq(Task::getApproval, taskPageParam.getApproval());
        }
        if(ObjectUtil.isNotEmpty(taskPageParam.getCurrentStatus())) {
            queryWrapper.lambda().eq(Task::getCurrentStatus, taskPageParam.getCurrentStatus());
        }
        if(ObjectUtil.isNotEmpty(taskPageParam.getHiddenLevel())) {
            queryWrapper.lambda().eq(Task::getHiddenLevel, taskPageParam.getHiddenLevel());
        }
        if(ObjectUtil.isNotEmpty(taskPageParam.getTaskName())) {
            queryWrapper.lambda().like(Task::getTaskName, taskPageParam.getTaskName());
        }
        if(ObjectUtil.isAllNotEmpty(taskPageParam.getReceiverDateStart(),taskPageParam.getReceiverDateEnd())) {
            queryWrapper.lambda().between(Task::getReceiverTime, DateUtil.beginOfDay(taskPageParam.getReceiverDateStart()), DateUtil.endOfDay(taskPageParam.getReceiverDateEnd()));
        }
        if(ObjectUtil.isAllNotEmpty(taskPageParam.getEndDateStart(),taskPageParam.getEndDateEnd())) {
            queryWrapper.lambda().between(Task::getEndTime, DateUtil.beginOfDay(taskPageParam.getEndDateStart()), DateUtil.endOfDay(taskPageParam.getEndDateEnd()));
        }
        // 判断是否分管领导
        if(StpUtil.hasRole("role_charge_leader")){
            queryWrapper.lambda().eq(Task::getChargeLeaderId,StpLoginUserUtil.getLoginUser().getId());
        }
        if(ObjectUtil.isAllNotEmpty(taskPageParam.getSortField(), taskPageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(taskPageParam.getSortOrder());
            queryWrapper.orderBy(true, taskPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(taskPageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByAsc(Task::getTaskId);
        }
        Page<Task> page = this.page(CommonPageRequest.defaultPage(), queryWrapper);
        for (Task task : page.getRecords()){
            if(ObjectUtil.isNotEmpty(task.getRewards())){
                task.setRewards(task.getRewards()/100);
            }
        }
        return page;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(TaskAddReq taskAddReq) {
        //获取登陆人
        SaBaseLoginUser saBaseLoginUser = StpLoginUserUtil.getLoginUser();
        //1、添加任务
        Task task = new Task();
        task.setTaskName(taskAddReq.getTaskName());
        task.setRequirements(taskAddReq.getRequirements());
        task.setRewards(taskAddReq.getRewards()*100.0);
        //2、反查隐患，获取隐患信息填入任务表信息
        HiddenReport hiddenReport = hiddenReportMapper.selectById(taskAddReq.getReportId());
        if (ObjectUtil.isEmpty(hiddenReport)){
            throw new CommonException("task","隐患查询出错，没有当前隐患！");
        }
        task.setReportId(taskAddReq.getReportId());
        task.setReportTime(hiddenReport.getCreateTime());
        task.setApproval(TaskApprovalEnum.WAIT_CHARGE_AUDIT.getValue());
        task.setAddress(hiddenReport.getAddress());
        task.setProvince(hiddenReport.getProvince());
        task.setCity(hiddenReport.getCity());
        task.setDistrict(hiddenReport.getDistrict());
        task.setLatitude(hiddenReport.getLatitude());
        task.setLongitude(hiddenReport.getLongitude());
        task.setHiddenLevel(hiddenReport.getHiddenLevel());
        //3、反向查询分管领导
        BizUser bizUser = bizUserMapper.selectById(hiddenReport.getChargeLeaderId());
        if (ObjectUtil.isEmpty(bizUser)){
            throw new CommonException("task","查询分管领导失败！");
        }
        task.setChargeLeaderId(bizUser.getId());
        task.setChargeLeaderName(bizUser.getName());
        this.save(task);

        // 写入审批记录
        TaskAuditRecord taskAuditRecord = new TaskAuditRecord();
        taskAuditRecord.setTaskId(task.getTaskId());
        taskAuditRecord.setTaskName("审核管理员发起流程");
        taskAuditRecord.setCreateUserId(saBaseLoginUser.getId());
        taskAuditRecord.setCreateUserName(saBaseLoginUser.getName());
        taskAuditRecord.setNextUserId(bizUser.getId());
        taskAuditRecord.setNextUserName(bizUser.getName());
        //当前状态
        taskAuditRecord.setCurrentStatus(TaskApprovalEnum.WAIT_ALLOCATE.getValue());
        //下一个状态
        taskAuditRecord.setNextStatus(TaskApprovalEnum.WAIT_CHARGE_AUDIT.getValue());
        taskAuditRecordService.save(taskAuditRecord);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(TaskEditParam taskEditParam) {
        Task task = this.queryEntity(taskEditParam.getTaskId());
        //获取登陆人
        SaBaseLoginUser saBaseLoginUser = StpLoginUserUtil.getLoginUser();
        task.setTaskName(taskEditParam.getTaskName());
        task.setRequirements(taskEditParam.getRequirements());
        task.setRewards(taskEditParam.getRewards()*100.0);
        task.setApproval(TaskApprovalEnum.WAIT_CHARGE_AUDIT.getValue());
        //3、反向查询分管领导
        BizUser bizUser = bizUserMapper.selectById(taskEditParam.getChargeLeaderId());
        if (ObjectUtil.isEmpty(bizUser)){
            throw new CommonException("task","查询分管领导失败！");
        }
        task.setChargeLeaderId(bizUser.getId());
        task.setChargeLeaderName(bizUser.getName());
        this.updateById(task);

        // 写入审批记录
        TaskAuditRecord taskAuditRecord = new TaskAuditRecord();
        taskAuditRecord.setTaskId(task.getTaskId());
        taskAuditRecord.setTaskName("审核管理员发起流程");
        taskAuditRecord.setCreateUserId(saBaseLoginUser.getId());
        taskAuditRecord.setCreateUserName(saBaseLoginUser.getName());
        taskAuditRecord.setNextUserId(bizUser.getId());
        taskAuditRecord.setNextUserName(bizUser.getName());
        //当前状态
        taskAuditRecord.setCurrentStatus(TaskApprovalEnum.WAIT_ALLOCATE.getValue());
        //下一个状态
        taskAuditRecord.setNextStatus(TaskApprovalEnum.WAIT_CHARGE_AUDIT.getValue());
        taskAuditRecordService.save(taskAuditRecord);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<TaskIdParam> taskIdParamList) {
        // 执行删除
        this.removeByIds(CollStreamUtil.toList(taskIdParamList, TaskIdParam::getTaskId));
    }

    @Override
    public Task detail(TaskIdParam taskIdParam) {
        return this.queryEntity(taskIdParam.getTaskId());
    }

    @Override
    public Task queryEntity(String id) {
        Task task = this.getById(id);
        if(ObjectUtil.isEmpty(task)) {
            throw new CommonException("任务表不存在，id值为：{}", id);
        }
        return task;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void chargeAudit(TaskAuditReq taskAuditReq) {
        //获取登陆人
        SaBaseLoginUser saBaseLoginUser = StpLoginUserUtil.getLoginUser();
        //1、修改状态查询任务
        Task task = this.getBaseMapper().selectById(taskAuditReq.getTaskId());
        if (ObjectUtil.isEmpty(task)){
            throw new CommonException("task","任务不存在！");
        }
        task.setRewards(taskAuditReq.getRewards()*100.0);
        task.setRequirements(taskAuditReq.getRequirements());
        task.setTaskName(taskAuditReq.getTaskName());

        TaskAuditRecord taskAuditRecord = new TaskAuditRecord();
        taskAuditRecord.setTaskId(taskAuditReq.getTaskId());
        taskAuditRecord.setTaskName("分管领导审批");
        taskAuditRecord.setCreateUserId(saBaseLoginUser.getId());
        taskAuditRecord.setCreateUserName(saBaseLoginUser.getName());

        //审批判定
        if(ObjectUtil.notEqual(AuditResultEnum.PASS.getValue(), taskAuditReq.getAuditResult())){
            //不通过
            task.setApproval(TaskApprovalEnum.WAIT_ALLOCATE.getValue());
            //写入审批记录
            taskAuditRecord.setAuditStatus(AuditResultEnum.NOT_PASS.getValue());
            //当前状态
            taskAuditRecord.setCurrentStatus(task.getApproval());
            //下一个状态
            taskAuditRecord.setNextStatus(TaskApprovalEnum.WAIT_ALLOCATE.getValue());
        }else {
            //不通过
            task.setApproval(TaskApprovalEnum.FINISHED.getValue());
            task.setCurrentStatus(TaskCurrentStatusEnum.RELEASED.getValue());
            task.setRewards(taskAuditReq.getRewards()*100.0);
            task.setRequirements(taskAuditReq.getRequirements());
            //写入审批记录
            taskAuditRecord.setAuditStatus(AuditResultEnum.PASS.getValue());
            //当前状态
            taskAuditRecord.setCurrentStatus(task.getApproval());
            //下一个状态
            taskAuditRecord.setNextStatus(TaskApprovalEnum.FINISHED.getValue());
            //下一个流程是审核管理员
            // 取审核管理员信息
            List<BizUser> bizUserList = bizUserMapper.listUserByRoleCode("role_audit");
            if(ObjectUtil.isEmpty(bizUserList)){
                throw new CommonException("未配置审核管理员！");
            }
            taskAuditRecord.setNextUserId(bizUserList.get(0).getId());
            taskAuditRecord.setNextUserName(bizUserList.get(0).getName());
        }
        taskAuditRecord.setRemark(taskAuditReq.getAuditRemark());
        this.getBaseMapper().updateById(task);
        taskAuditRecordService.save(taskAuditRecord);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void assignmentUser(AssigmentUserReq assigmentUserReq) {
        //获取登陆人
        SaBaseLoginUser saBaseLoginUser = StpLoginUserUtil.getLoginUser();
        //1、通过任务id和申请人员id 查询申请单
        TaskAssignment taskAssignment = taskAssignmentMapper.selectOne(new LambdaQueryWrapper<TaskAssignment>().eq(TaskAssignment::getTaskId, assigmentUserReq.getTaskId()).eq(TaskAssignment::getAppletUserId, assigmentUserReq.getAppletUserId()));
        if (ObjectUtil.isNull(taskAssignment)){
            throw new CommonException("task","申请单不存在！");
        }
        taskAssignment.setAssignmentStatus(AssignmentStatusEnum.ASSIGNED.getValue());
        taskAssignment.setAssignmentId(saBaseLoginUser.getId());
        taskAssignment.setAppletPlatformUserName(saBaseLoginUser.getName());
        taskAssignment.setAssignmentTime(DateUtil.date());
        //修改任务
        Task task = this.baseMapper.selectById(taskAssignment.getTaskId());
        task.setCurrentStatus(TaskCurrentStatusEnum.EXECUTING.getValue());
        task.setReceiverAppletUserId(taskAssignment.getAppletUserId());
        task.setReceiverTime(DateUtil.date());
        this.baseMapper.updateById(task);
        taskAssignmentMapper.updateById(taskAssignment);
    }

    @Override
    public void taskJudge(TaskJudgeReq taskJudgeReq) {
        Task task = this.baseMapper.selectById(taskJudgeReq.getTaskId());
        if (ObjectUtil.isEmpty(task)){
            //抛出异常
            throw new CommonException("task","任务不存在！");
        }
        //修改任务状态
        if (taskJudgeReq.getVerifyResult().equals("1")){
            task.setCurrentStatus(TaskCurrentStatusEnum.FINISHED.getValue());
        }else {
            task.setCurrentStatus(TaskCurrentStatusEnum.FAILED.getValue());
        }
        task.setTaskRemark(taskJudgeReq.getTaskRemark());
        this.baseMapper.updateById(task);
    }

    @Override
    public void issueReward(TaskIdParam taskIdParam) {
        Task task = this.queryEntity(taskIdParam.getTaskId());
        // 验证状态
        if(ObjectUtil.notEqual(task.getCurrentStatus(), TaskCurrentStatusEnum.FINISHED.getValue())){
            throw new CommonException("任务未结束，无法发放奖励！");
        }
        AppletUser appletUser = appletUserMapper.selectById(task.getReceiverAppletUserId());
        if(ObjectUtil.isEmpty(appletUser) || StrUtil.isBlank(appletUser.getPhone())){
            throw new CommonException("上报人信息不全，无法发放奖励！");
        }
        task.setPayed(1);
        this.baseMapper.updateById(task);
        // 调用接口发放奖励
        this.rewardsLogService.taskRewards(task, appletUser);
    }
}
